//
//  UIView+CycleExtendTouchRect.m
//  CycleControlFunction
//
//  Created by ddy on 2018/8/7.
//  Copyright © 2018年 ddy. All rights reserved.
//

#import "UIView+CycleExtendTouchRect.h"
#import <objc/runtime.h>


void Swizzle(Class c ,SEL origin, SEL new){
    Method originMethod = class_getInstanceMethod(c, origin);
    Method newMethod = class_getInstanceMethod(c, new);
    ///判断 新的方法newMethod 是否能添加到原来origin方法上
    //IMP : method_getImplementation
    if(class_addMethod(c, origin, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))){
        ///如果添加上了，就用new新的方法，替换originMethod原来的方法
        class_replaceMethod(c, new, method_getImplementation(originMethod), method_getTypeEncoding(originMethod));
    } else {
        //直接替换
        method_exchangeImplementations(originMethod, newMethod);
    }
}
@implementation UIView (CycleExtendTouchRect)
/*
 实现思路就是替换 pointInside:withEvent: 或者 hitTest:withEvent: 方法。顺便再复习一下响应链传递机制：当手指触摸屏幕，UIWindow 从最底层开始向上分发事件，每到一个视图，先调用 hitTest:withEvent: ，在 hitTest:withEvent: 里调用 pointInside:withEvent: 判断触摸点是否在当前区域，如果在，遍历它的子视图递归调用 hitTest:withEvent:
 */
+ (void)load{
    Swizzle(self, @selector(pointInside:withEvent:), @selector(myPointInside:withEvent:));
}
//递归
- (BOOL)myPointInside:(CGPoint)point withEvent:(UIEvent *)event{
    if(UIEdgeInsetsEqualToEdgeInsets(self.cycle_touchExtendInset, UIEdgeInsetsZero) || self.hidden || ([self isKindOfClass:UIControl.class] && !((UIControl *)self).enabled)){
        return [self myPointInside:point withEvent:event];
    }
    CGRect hitFrame = UIEdgeInsetsInsetRect(self.bounds, self.cycle_touchExtendInset);
    hitFrame.size.width = MAX(hitFrame.size.width, 0);
    hitFrame.size.height = MAX(hitFrame.size.height, 0);
    return CGRectContainsPoint(hitFrame, point);
    
}
///设置可点击范围
static char touchExtendInsetsKey;
- (void)setCycle_touchExtendInset:(UIEdgeInsets)cycle_touchExtendInset{
    objc_setAssociatedObject(self, &touchExtendInsetsKey, [NSValue valueWithUIEdgeInsets:cycle_touchExtendInset], OBJC_ASSOCIATION_RETAIN);
}
- (UIEdgeInsets)cycle_touchExtendInset {
    return [objc_getAssociatedObject(self, &touchExtendInsetsKey) UIEdgeInsetsValue];
}









@end
